import axios, {
  AxiosInstance,
  AxiosResponse,
  AxiosError,
} from "axios";
import { Platform } from "react-native";
import userManager from "./userManager";

// Logger function, you can replace it with any logger you prefer
const logger = {
  d: console.log,
  e: console.error,
};

class HttpManager {
  private static instance: HttpManager;
  private axiosInstance: AxiosInstance;

  private constructor() {
  
    this.axiosInstance = axios.create();
    
    // Handle certificate errors and custom configurations
    this.axiosInstance.interceptors.request.use(
      async (config) => {
        logger.d(`Request: ${config.url}`, config.headers);
        return config;
      },
      (error: AxiosError) => {
        logger.e("Request Error: ", error.message);
        return Promise.reject(error);
      }
    );

    // Response Interceptor
    this.axiosInstance.interceptors.response.use(
      (response: AxiosResponse) => {
        logger.d(`Response: ${response.config.url}`, response.data);
        return response;
      },
      (error: AxiosError) => {
        this.handleError(error);
        return Promise.reject(error);
      }
    );
  }

  // Singleton instance
  public static getInstance(): HttpManager {
    if (!HttpManager.instance) {
      HttpManager.instance = new HttpManager();
    }
    return HttpManager.instance;
  }

  // GET request method
  public async get(
    url: string,
    params?: any
  ): Promise<AxiosResponse<any, any> | undefined> {
    try {
      logger.d(`GET request to: ${url}`);

      const token = userManager.UserInfo?.token ?? '';
      const uid = userManager.UserInfo?.uid ?? ''; 

      const headers: Record<string, string> = {
        "Content-Type": "application/x-www-form-urlencoded",
        Accept: "application/json",
        authorization: `metatube-${token}`,
        uid: uid ?? "",
        env: "ideaflow",
        c: Platform.OS, // 'android', 'ios', 'macos', 'windows', or 'web'
        pg: "10",
        version: "20240912", // Replace with actual version if needed
      };

      const response = await this.axiosInstance.get(url, {
        params: params,
        headers: headers,
      });
      return response;
    } catch (error) {
      logger.e("GET request error: ", error);
    }
  }

  // POST request method
  public async post(
    url: string,
    data?: any
  ): Promise<AxiosResponse<any, any> | undefined> {
    try {
      //logger.d(`POST request to: ${url}`);
      const token = userManager.UserInfo?.token ?? '';
      const uid = userManager.UserInfo?.uid ?? ''; 

      const headers: Record<string, string> = {
        "Content-Type": "application/json",
        Accept: "application/json",
        authorization: `metatube-${token}`,
        uid: uid ?? "",
        env: "ideaflow",
        c: Platform.OS, // Automatically detects the platform ('android', 'ios', etc.)
        pg: "10",
      };
      const response = await this.axiosInstance.post(url, data, {
        headers: headers,
      });
      return response;
    } catch (error) {
      logger.e("POST request error: ", error);
    }
  }

  // Image Upload
  public async uploadImage(
    url: string,
    imageFile: any
  ): Promise<AxiosResponse<any, any> | undefined> {
    try {
      const formData = new FormData();
      formData.append("mFile", {
        uri: imageFile.uri,
        type: "image/jpeg",
        name: "mFile.jpeg",
      });

      const token = userManager.UserInfo?.token ?? '';
      const uid = userManager.UserInfo?.uid ?? ''; 

      const headers: Record<string, string> = {
        "Content-Type": "multipart/form-data",
        Accept: "application/json",
        authorization: `metatube-${token}`,
        uid: uid ?? "",
        env: "ideaflow",
        c: Platform.OS, // Automatically detects the platform ('android', 'ios', etc.)
        pg: "10",
      };

      const response = await this.axiosInstance.post(url, formData, {
        headers: headers,
      });

      logger.d(`Image uploaded to: ${url}`);
      return response;
    } catch (error) {
      logger.e("Image upload error: ", error);
    }
  }

  // Private method to handle errors
  private handleError(error: AxiosError) {
    if (error.response) {
      logger.e(`Error Response Code: ${error.response.status}`);
      logger.e(`Error Response Data: ${JSON.stringify(error.response.data)}`);
    } else if (error.request) {
      logger.e("No response received from the server");
    } else {
      logger.e(`Error Message: ${error.message}`);
    }
  }
}

// Usage Example
const httpManager = HttpManager.getInstance();

export default httpManager;
